import React, {Component} from 'react';
import {
  Chart as ChartJS,
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  Title,
  Tooltip,
  Legend,
} from 'chart.js';
import { Line } from 'react-chartjs-2';
import faker from 'faker';
require("whatwg-fetch");

ChartJS.register(
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  Title,
  Tooltip,
  Legend
);

export const options = {
  responsive: true,
  interaction: {
    mode: 'index' as const,
    intersect: false,
  },
  stacked: false,
  plugins: {
    title: {
      display: true,
      text: '空气能温度',
    },
  },
  scales: {
    x:{
      ticks:{
        autoSkip:true,
        autoSkipPadding:100
      }
    },
    y: {
      type: 'linear' as const,
      display: true,
      position: 'left' as const,
    },
    y1: {
      type: 'linear' as const,
      display: true,
      position: 'right' as const,
      grid: {
        drawOnChartArea: false,
      },
    },
  },
};

//-30C ~100C NTC 3950 100K whit 1M Cable 1%
const ntc100k2 = [
  1733.2000,
  1630.4080,
  1534.4770,
  1444.9030,
  1361.2200,
  1283.0000,
  1209.3270,
  1140.4240,
  1075.9490,
  1015.5880, 
  959.0500,
  906.0117,
  856.2883,
  809.6506,
  765.8865,
  724.8000,
  685.6507,
  648.8929,
  614.3649,
  581.9169,
  551.4100,
  522.6908,
495.6674,
470.2286,
446.2714,
423.7000,
402.0560,
381.6658,
362.4488,
344.3301,
327.2400,
311.0397,
295.7506,
281.3157,
267.6820,
254.8000,
242.5827,
231.0321,
220.1080,
209.7724,
199.9900,
190.5578,
181.6319,
173.1822,
165.1804,
157.6000,
150.4253,
143.6234,
137.1726,
131.0528,
125.2450,
119.6582,
114.3559,
109.3221,
104.5415,
100.0000,
95.8191,
91.8392,
88.0494,
84.4395,
81.0000,
77.6238,
74.4091,
71.3472,
68.4301,
65.6500,
62.9838,
60.4420,
58.0181,
55.7060,
53.5000,
51.3708,
49.3391,
47.3998,
45.5483,
43.7800,
42.0555,
40.4092,
38.8369,
37.3350,
35.8999,
34.6160,
33.3855,
32.2059,
31.0748,
29.9900,
28.9053,
27.8660,
26.8700,
25.9153,
25.0000,
24.1099,
23.2565,
22.4381,
21.6531,
20.9000,
20.1741,
19.4774,
18.8087,
18.1666,
17.5500,
16.9459,
16.3659,
15.8089,
15.2739,
14.7600,
14.2813,
13.8206,
13.3774,
12.9507,
12.5400,
12.1347,
11.7447,
11.3694,
11.0080,
10.6600,
10.3243,
10.0010,
9.6895,  
9.3893,
9.1000,
8.8171,
8.5444,
8.2816,
8.0283,
7.7840,
7.5538,
7.3316,
7.1172,
6.9100,
6.7100
];
//-30C ~ 100C NTC 100K B值3950 R/T表<热敏电阻温度/阻值对照表>
//http://www.thermistors.cn/news/287.html
const ntc100k = [
1787.9797	,
1679.6017	,
1578.5061	,
1484.1584	,
1396.0662	,
1313.7754	,
1236.8685	,
1164.9598	,
1097.6941	,
1034.7432	,
975.8038	,
920.5962	,
868.8615	,
820.3603	,
774.871		,
732.1889	,
692.1238	,
654.4999	,
619.154		,
585.9346	,
554.7016	,
525.3245	,
497.6821	,
471.6621	,
447.1599	,
424.0781	,
402.3264	,
381.8204	,
362.4818	,
344.2375	,
327.0195	,
310.764		,
295.4121	,
280.9084	,
267.2014	,
254.2428	,
241.9877	,
230.394		,
219.4224	,
209.0361	,
199.2007	,
189.8841	,
181.0559	,
172.6881	,
164.754		,
157.229		,
150.0898	,
143.3144	,
136.8825	,
130.7749	,
124.9734	,
119.4612	,
114.2223	,
109.2417	,
104.5053	,
100			,
95.7132		,
91.6333		,
87.7492		,
84.0505		,
80.5274		,
77.1707		,
73.9717		,
70.9222		,
68.0144		,
65.2411		,
62.5954		,
60.0707		,
57.661		,
55.3604		,
53.1635		,
51.0651		,
49.0602		,
47.1443		,
45.313		,
43.5621		,
41.8878		,
40.2862		,
38.7539		,
37.2876		,
35.8842		,
34.5405		,
33.2538		,
32.0214		,
30.8408		,
29.7096		,
28.6253		,
27.586		,
26.5895		,
25.6338		,
24.7171		,
23.8376		,
22.9937		,
22.1836		,
21.4061		,
20.6594		,
19.9424		,
19.2537		,
18.592		,
17.9562		,
17.3452		,
16.7578		,
16.193		,
15.6499		,
15.1276		,
14.6251		,
14.1417		,
13.6764		,
13.2286		,
12.7976		,
12.3825		,
11.9828		,
11.5978		,
11.227		,
10.8697		,
10.5254		,
10.1935		,
9.8736		,
9.5652		,
9.2678		,
8.9809		,
8.7042		,
8.4373		,
8.1797		,
7.9312		,
7.6912		,
7.4596		,
7.236		,
7.0201		,
6.8115		,
6.6101
];

//根据公式计算温度
//例如：100k,b 3950, t2=25, r2=100
function calc_temp(r:number,b:number,t2:number,r2:number){
  const tk = 273.15;
  return 1./(1./(t2+tk) + Math.log(r/r2)/b)-tk;
}

//使用差值法计算电阻值对应的温度
function linear_ntc100k_calc(r:number):number{
  const ntc = ntc100k2
  for(let i = 1;i<ntc.length;i++){
    if(r>ntc[i]){
      return i-30-(r-ntc[i])/(ntc[i-1]-ntc[i]);
    }
  }
  return 0.;
}

function value2temp(v:number):number{
  return linear_ntc100k_calc(100.*v/(1024.-v));
}

function calc_temp_b3950(v:number):number{
  return calc_temp(100.*v/(1024.-v),3950,25,95.);
}

function calc_temp_b3275(v:number):number{
  return calc_temp(100.*v/(1024.-v),3275,25,100.);
}

// 定义温度数据接口
interface TempData {
    time: number;
    t0: number;
    t1: number;
    t2: number;
    t3: number;
    t4: number;
    t5: number;
    t6: number;
    t7: number;
}

// 需要添加 Props 和 State 接口定义
interface AppProps {
    minutes: number;
    nday: number;
}

interface AppState {
    msg: string;
    temps: TempData[]; // 替换 any[]
}

class App extends Component<AppProps, AppState> {
  // 添加 timer 属性声明
  private timer: NodeJS.Timeout | null = null;
  
  state = {
    msg:"ready...",
    temps:[]
  }    

  constructor(props: AppProps) {
    super(props);
    this.state = {
        msg: "ready...",
        temps: []
    };
  }

  componentDidMount(){
    console.log("componentDidMount");
    let {minutes,nday} = this.props;
    this.fetch_data(minutes,nday);
    this.timer = setInterval(() => {
        const { minutes, nday } = this.props;
        this.fetch_data(minutes, nday);
    }, 1000 * 60);
  }

  componentWillUnmount(){
    console.log("componentWillUnmount")
    if (this.timer) {
        clearInterval(this.timer);
    }
  }

  /**
   * 获取温度数据
   * @param minutes - 分钟数，当nday为0时使用
   * @param nday - 天数，当不为0时使用此参数
   */
  async fetch_data(minutes: number, nday: number) {
    // 根据nday选择不同的API端点
    const url = nday === 0 ? '/adc/temp' : '/adc/temp_nday';
    
    try {
        const response = await fetch(url, {
            method: 'POST',
            credentials: 'same-origin',
            headers: { 'Content-Type': 'application/json' },
            // 根据nday决定发送minutes还是nday作为参数n
            body: JSON.stringify({ n: nday === 0 ? minutes : nday })
        });

        // 检查响应状态
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }

        // 解析响应数据并更新状态
        const data = await response.json();
        this.setState({ temps: data.data });
    } catch (error) {
        console.error('数据获取错误:', error);
        // 可以添加错误状态处理
    }
  }

  componentDidUpdate(prevProps, prevState){
    console.log("componentDidUpdate");
    if(prevProps.minutes!=this.props.minutes||this.props.minutes==null||prevProps.nday!=this.props.nday){
      let {minutes,nday} = this.props;
        console.log("componetDidUpdate fetch_data");
        this.fetch_data(minutes,nday);
        return true;   
    }    
  }

  render(){
    let temps = this.state.temps
    // 初始化数据数组时明确声明类型
    let timestamp: string[] = []
    let adc0: number[] = []
    let adc1: number[] = []
    let adc2: number[] = []
    let adc3: number[] = []
    let adc4: number[] = []
    let adc5: number[] = []
    let adc6: number[] = []
    let adc7: number[] = []
    console.log("render:"+temps.length);
    // 处理温度数据
    for(let i=0;i<temps.length;i++){
      // 转换时间戳为本地时间字符串
      let t = new Date(temps[i]['time']*1000);
        timestamp.push(t.toLocaleDateString()+" "+t.toLocaleTimeString());
        // 计算各个传感器的温度值
        adc0.push(calc_temp_b3275(temps[i]['t0']));
        adc1.push(calc_temp_b3275(temps[i]['t1']));
        adc2.push(calc_temp_b3275(temps[i]['t2']));
        adc3.push(calc_temp_b3275(temps[i]['t3']));
        adc4.push(calc_temp_b3275(temps[i]['t4']));
        adc5.push(calc_temp_b3275(temps[i]['t5']));
        adc6.push(calc_temp_b3275(temps[i]['t6']));
        adc7.push(calc_temp_b3275(temps[i]['t7']));
    }
    // 构建图表数据
    const k = temps.length-1;  // 最新数据索引
    let data = {
      labels: timestamp,
      datasets: [
        {
          label: `入(4)${k>=0?adc3[k].toFixed(2):0}°C`,
          data: adc3,
          pointStyle: 'none',
          spanGaps: true,
          borderColor: 'rgb(255, 0, 0)',
          backgroundColor: 'rgba(255, 0, 0, 0.5)',
          yAxisID: 'y',
        },    
        {
          label: `回(6)${k>=0?adc5[k].toFixed(2):0}°C`,
          data: adc5,
          pointStyle: 'none',
          spanGaps: true,
          borderColor: 'rgb(0, 255, 128)',
          backgroundColor: 'rgba(0, 255, 128, 0.5)',
          yAxisID: 'y',
        },            
        {
          label: `厨房(1)${k>=0?adc0[k].toFixed(2):0}°C`,
          data: adc0,
          pointStyle: 'none',
          spanGaps: true,
          borderColor: 'rgb(128, 128, 128)',
          backgroundColor: 'rgba(128, 128, 128, 0.5)',
          yAxisID: 'y',
        },
        {
          label: `北卧(3)${k>=0?adc2[k].toFixed(2):0}°C`,
          data: adc2,
          pointStyle: 'none',
          spanGaps: true,
          borderColor: 'rgb(200, 200, 200)',
          backgroundColor: 'rgba(200, 200, 200, 0.5)',
          yAxisID: 'y',
        },
        {
          label: `西卧(2)${k>=0?adc1[k].toFixed(2):0}°C`,
          data: adc1,
          pointStyle: 'none',
          spanGaps: true,
          borderColor: 'rgb(53, 235, 162)',
          backgroundColor: 'rgba(53, 235, 162, 0.5)',
          yAxisID: 'y',
        },
        {
          label: `办(5)${k>=0?adc4[k].toFixed(2):0}°C`,
          data: adc4,
          pointStyle: 'none',
          spanGaps: true,
          borderColor: 'rgb(128, 128, 255)',
          backgroundColor: 'rgba(128, 128, 255, 0.5)',
          yAxisID: 'y',
        },
        {
          label: `东卧回(7)${k>=0?adc6[k].toFixed(2):0}°C`,
          data: adc6,
          pointStyle: 'none',
          spanGaps: true,
          borderColor: 'rgb(0, 128, 255)',
          backgroundColor: 'rgba(0, 128, 255, 0.5)',
          yAxisID: 'y',
        },
        {
          label: `东卧(8)${k>=0?adc7[k].toFixed(2):0}°C`,
          data: adc7,
          pointStyle: 'none',
          spanGaps: true,
          borderColor: 'rgb(255, 255, 0)',
          backgroundColor: 'rgba(255, 255, 0, 0.5)',
          yAxisID: 'y',
        }      
      ],
    };      
    return <Line style={{width:"100%",height:"100%"}} options={options} data={data} />;
  }
}

export default App;